#include "server_core.hpp"
#include "../common/thread_pool.hpp"
#include "../common/user_manager.hpp"
#include "../common/room_manager.hpp"
#include "../common/utils.hpp"
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <iostream>
#include <sstream>

static ThreadPool* pool = nullptr;
const std::string ADMIN_NAME = "tbx";
const std::string ADMIN_PASSWORD = "151211";
std::unordered_map<int, bool> pending_admin_auth;

void init_server_core(ThreadPool* p) {
    pool = p;
}

void send_msg(int fd, const std::string& msg) {
    send(fd, msg.c_str(), msg.size(), 0);
}

bool check_admin(int fd) {
    if (!user_manager.is_admin(fd)) {
        send_msg(fd, wrap_color("[Server] You are not authorized to use this command.\n", COLOR_RED));
        return false;
    }
    return true;
}

void register_client(int fd) {
    user_manager.add_user(fd);
    std::cout << "[Server] New connection: fd=" << fd << std::endl;
    send_msg(fd, wrap_color("[Server] Please enter your nickname:\n", COLOR_YELLOW));
}

void unregister_client(int fd) {
    std::string name = user_manager.get_name(fd);
    std::string msg = wrap_color("[Server] " + name + " left the chat.\n", COLOR_RED);
    for (int client : user_manager.get_all_fds()) {
        if (client != fd) send_msg(client, msg);
    }
    std::cout << msg;
    log_to_file(msg);
    user_manager.remove_user(fd);
    close(fd);
}

void handle_client_message(int fd, const std::string& msg) {
    pool->enqueue([fd, msg]() {
        if (pending_admin_auth.count(fd)) {
            if (msg == ADMIN_PASSWORD) {
                user_manager.add_admin(fd);
                send_msg(fd, wrap_color("[Server] Admin login successful.\n", COLOR_GREEN));
            } else {
                send_msg(fd, wrap_color("[Server] Wrong password. You are not admin.\n", COLOR_RED));
                user_manager.rename_user(fd, "anonymous");
                send_msg(fd, wrap_color("[Server] Please enter your nickname:\n", COLOR_YELLOW));
            }
            pending_admin_auth.erase(fd);
            return;
        }

        if (user_manager.get_name(fd) == "anonymous") {
            if (msg.empty()) {
                send_msg(fd, wrap_color("[Server] Nickname cannot be empty.\n", COLOR_RED));
                return;
            }
            if (user_manager.name_exists(msg)) {
                send_msg(fd, wrap_color("[Server] This nickname is already taken.\n[Server] Please enter a different nickname:\n", COLOR_RED));
                return;
            }
            if (msg == ADMIN_NAME) {
                pending_admin_auth[fd] = true;
                user_manager.rename_user(fd, ADMIN_NAME);
                send_msg(fd, wrap_color("[Server] Enter admin password:\n", COLOR_YELLOW));
                return;
            }
            if (user_manager.is_banned(msg)) {
                send_msg(fd, wrap_color("[Server] You are banned.\n", COLOR_RED));
                unregister_client(fd);
                return;
            }
            user_manager.rename_user(fd, msg);
            send_msg(fd, wrap_color("[Server] Welcome, " + msg + "!\n", COLOR_GREEN));

            std::string notice = wrap_color("[Server] " + msg + " joined the chat.\n", COLOR_GREEN);
            for (int client : user_manager.get_all_fds()) {
                if (client != fd) send_msg(client, notice);
            }
            std::cout << notice;
            log_to_file(notice);
            return;
        }

        if (msg.empty()) {
            send_msg(fd, wrap_color("[Server] Empty message not allowed.\n", COLOR_RED));
            return;
        }

        const std::string name = user_manager.get_name(fd);

        if (msg == "/who") {
            std::string list = wrap_color("[Server] Online users:\n", COLOR_GREEN);
            for (int client : user_manager.get_all_fds()) {
                list += " - " + user_manager.get_name(client) + "\n";
            }
            send_msg(fd, list);
            return;
        }
        else if (msg.rfind("/rename ", 0) == 0) {
            std::string newname = msg.substr(8);
            if (newname.empty()) {
                send_msg(fd, wrap_color("[Server] Usage: /rename <newname>\n", COLOR_RED));
                return;
            }
            if (user_manager.name_exists(newname)) {
                send_msg(fd, wrap_color("[Server] This name is already taken.\n", COLOR_RED));
                return;
            }
            if (newname == ADMIN_NAME) {
                pending_admin_auth[fd] = true;
                send_msg(fd, wrap_color("[Server] Enter admin password to rename:\n", COLOR_YELLOW));
                return;
            }
            std::string oldname = name;
            user_manager.rename_user(fd, newname);
            send_msg(fd, wrap_color("[Server] Your name is now " + newname + ".\n", COLOR_GREEN));

            std::string notice = wrap_color("[Server] " + oldname + " is now known as " + newname + ".\n", COLOR_YELLOW);
            for (int client : user_manager.get_all_fds()) {
                if (client != fd) send_msg(client, notice);
            }
            std::cout << notice;
            log_to_file(notice);
            return;
        }
        // 其余命令部分略（可按相同方式替换所有 COLOR_ 开头的 send_msg 内容）
        // ...前略...

        else if (msg.rfind("/kick ", 0) == 0) {
            std::string target = msg.substr(6);
            if (!check_admin(fd)) return;
            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd == -1) {
                send_msg(fd, wrap_color("[Server] User not found.\n", COLOR_RED));
                return;
            }
            send_msg(target_fd, wrap_color("[Server] You have been kicked from the chat.\n", COLOR_RED));
            std::string info = wrap_color("[Server] User " + target + " was kicked.\n", COLOR_RED);
            for (int client : user_manager.get_all_fds()) {
                if (client != target_fd) send_msg(client, info);
            }
            log_to_file(info);
            unregister_client(target_fd);
            return;
        }
        else if (msg.rfind("/mute ", 0) == 0) {
            std::string target = msg.substr(6);
            if (!check_admin(fd)) return;
            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd == -1) {
                send_msg(fd, wrap_color("[Server] User not found.\n", COLOR_RED));
                return;
            }
            user_manager.mute_user(target_fd);
            send_msg(fd, wrap_color("[Server] " + target + " has been muted.\n", COLOR_YELLOW));
            return;
        }
        else if (msg.rfind("/unmute ", 0) == 0) {
            std::string target = msg.substr(8);
            if (!check_admin(fd)) return;
            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd == -1) {
                send_msg(fd, wrap_color("[Server] User not found.\n", COLOR_RED));
                return;
            }
            user_manager.unmute_user(target_fd);
            send_msg(fd, wrap_color("[Server] " + target + " has been unmuted.\n", COLOR_GREEN));
            return;
        }
        else if (msg.rfind("/to ", 0) == 0) {
            std::istringstream iss(msg);
            std::string cmd, target, word;
            iss >> cmd >> target;
            std::string message;
            while (iss >> word) message += word + " ";
            if (user_manager.is_muted(fd)) {
                send_msg(fd, wrap_color("[Server] You are muted and cannot send private messages.\n", COLOR_RED));
                return;
            }
            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd != -1) {
                std::string out = wrap_color("[PM from " + name + "]: " + message + "\n", COLOR_YELLOW);
                send_msg(target_fd, out);
                log_to_file(out);
            } else {
                send_msg(fd, wrap_color("[Server] User not found.\n", COLOR_RED));
            }
            return;
        }
        else if (msg.rfind("/ban ", 0) == 0) {
            std::string target = msg.substr(5);
            if (!check_admin(fd)) return;
            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd == -1) {
                send_msg(fd, wrap_color("[Server] User not found.\n", COLOR_RED));
                return;
            }
            user_manager.ban_user(target);
            send_msg(fd, wrap_color("[Server] " + target + " has been banned.\n", COLOR_YELLOW));
            std::string notice = wrap_color("[Server] " + target + " was banned and disconnected.\n", COLOR_RED);
            for (int client : user_manager.get_all_fds()) {
                if (client != target_fd) send_msg(client, notice);
            }
            log_to_file(notice);
            unregister_client(target_fd);
            return;
        }
        else if (msg.rfind("/unban ", 0) == 0) {
            std::string target = msg.substr(7);
            if (!check_admin(fd)) return;
            user_manager.unban_user(target);
            send_msg(fd, wrap_color("[Server] " + target + " has been unbanned.\n", COLOR_GREEN));
            return;
        }
        else if (msg == "/adminlist") {
            std::string list = wrap_color("[Server] Admins online:\n", COLOR_GREEN);
            for (int client : user_manager.get_all_fds()) {
                if (user_manager.is_admin(client)) {
                    list += " - " + user_manager.get_name(client) + "\n";
                }
            }
            send_msg(fd, list);
            return;
        }
        else if (msg == "/room") {
            std::string room = room_manager.get_room(fd);
            if (room.empty()) room = "lobby";
            send_msg(fd, wrap_color("[Server] You are in room: " + room + "\n", COLOR_GREEN));
            return;
        }
        else if (msg == "/members") {
            std::string room = room_manager.get_room(fd);
            std::set<int> members = room_manager.get_room_members(room);
            std::string output = wrap_color("[Server] Room: " + room + "\n[Server] Members:\n", COLOR_GREEN);
            for (int member_fd : members) {
                output += " - " + user_manager.get_name(member_fd) + "\n";
            }
            send_msg(fd, output);
            return;
        }
        else if (msg == "/quit") {
            send_msg(fd, wrap_color("[Server] You have disconnected.\n", COLOR_RED));
            unregister_client(fd);
            return;
        }
        else if (msg.substr(0, 6) == "/join ") {
            std::istringstream iss(msg);
            std::string cmd, room, pwd;
            iss >> cmd >> room >> pwd;
            bool success = room_manager.join_room(fd, room, pwd);
            if (success) {
                send_msg(fd, wrap_color("[Server] You joined room: " + room + "\n", COLOR_GREEN));
            } else {
                send_msg(fd, wrap_color("[Server] Failed to join room (wrong password?).\n", COLOR_RED));
            }
            return;
        }
        else if (msg == "/leave") {
            room_manager.leave_room(fd);
            send_msg(fd, wrap_color("[Server] You left the room.\n", COLOR_YELLOW));
            return;
        }
        else if (msg == "/help") {
            std::string help = wrap_color(
                "[Server] Available commands:\n"
                " - /who: Show online users\n"
                " - /rename <newname>\n"
                " - /to <user> <msg>: Private message\n"
                " - /room: Show your room\n"
                " - /members: List room members\n"
                " - /join <room> <pwd>: Join/create room\n"
                " - /leave: Leave current room\n"
                " - /quit: Disconnect\n"
                " - /adminlist: Show admins\n"
                " - /kick, /mute, /unmute, /ban, /unban: Admin only\n"
                " - /help: Show this message\n", COLOR_YELLOW);
            send_msg(fd, help);
            return;
        }
        if (user_manager.is_muted(fd)) {
            send_msg(fd, wrap_color("[Server] You are muted and cannot send messages.\n", COLOR_RED));
            return;
        }

        if (msg[0] == '/' && msg.substr(0, 1) == "/") {
            send_msg(fd, wrap_color("[Server] Unknown command. Type /help for list.\n", COLOR_RED));
            return;
        }

        std::string output = "[" + name + "]: " + msg + "\n";
        std::string colored = wrap_color(output, COLOR_RESET);
        for (int client : user_manager.get_all_fds()) {
            if (client != fd) send_msg(client, colored);
        }
        log_to_file(output);
    });
}

